package com.ktwlsoft.fundmanage.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigInteger;
import java.security.MessageDigest;

/**
 * 基础平台MD5签名
 * @author Administrator
 *
 */
public class MD5 {

    /** 日志对象 **/
    private static Logger logger = LoggerFactory.getLogger(MD5.class);

	public static final String KEY_MAC = "HmacMD5";

	public static String encryptHMAC(byte[] data, String key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key.getBytes("UTF-8"), KEY_MAC);
        String keys =secretKey.getAlgorithm();
        Mac mac = Mac.getInstance(keys);
        mac.init(secretKey);
        byte[] md5Byte =mac.doFinal(data);
        return byteArrayToHexString(md5Byte);
    }

	/**
	 * byte数组转换为HexString
	 */
    public static String byteArrayToHexString(byte[] b) {
        StringBuffer sb = new StringBuffer(b.length * 2);
        for (int i = 0; i < b.length; i++) {
            int v = b[i] & 0xff;
            if (v < 16) {
                sb.append('0');
            }
            sb.append(Integer.toHexString(v));
        }
        return sb.toString();
    }
    /**
     * 将16进制字符串转换为byte[]
     *
     * @param str str
     * @return byte[]
     */
    public static byte[] toBytes(String str) {
        if(str == null || str.trim().equals("")) {
            return new byte[0];
        }
        byte[] bytes = new byte[str.length() / 2];
        final int numTwo=2;
        for(int i = 0; i < str.length() / numTwo; i++) {
            String subStr = str.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }
        return bytes;
    }

    public static String md5(String str) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        md.update(str.getBytes("UTF-8"));
        byte b[] = md.digest();
        int i;
        StringBuffer buf = new StringBuffer("");
        for (int offset = 0; offset < b.length; offset++) {
            i = b[offset];
            if (i < 0) {
				i += 256;
			}
            if (i < 16) {
				buf.append("0");
			}
            buf.append(Integer.toHexString(i));
        }
        str = buf.toString();
        return str;
    }

    public static String encrypt(String str) throws Exception {
        // 生成一个MD5加密计算摘要
        MessageDigest md = MessageDigest.getInstance("MD5");
        // 计算md5函数
        md.update(str.getBytes("UTF-8"));
        // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
        // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
        return new BigInteger(1, md.digest()).toString(16);
    }

    /**
     * 对字符串md5加密(大写+数字)
     *
     * @param str 传入要加密的字符串
     * @return  MD5加密后的字符串
     */
    public static String encryptUpperCase(String str) {
        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
        try {
            byte[] btInput = str.getBytes("UTF-8");
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char strs[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                strs[k++] = hexDigits[byte0 >>> 4 & 0xf];
                strs[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(strs);
        }
        catch (RuntimeException e) {
            throw e;
         }
        catch (Exception e) {
            logger.error(e.getMessage());
            return null;
        }
    }

	// public static void main(String[] args) throws Exception {
    //     System.out.println(md5("123456"));
    // }
}
